﻿Imports System.Web
Imports System.Web.Services
Imports System.Text
Imports System.Xml

Namespace DotNetNuke.Modules.ActiveForums.Handlers
    Public Class forumhelper
        Inherits HandlerBase
        Public Enum Actions
            None
            UserPing
            GetUsersOnline
            TopicSubscribe
            ForumSubscribe
            RateTopic
            DeleteTopic
            MoveTopic
            PinTopic
            LockTopic
            MarkAnswer
            TagsAutoComplete
            DeletePost
            LoadTopic
            SaveTopic
            ForumList
        End Enum
        Overrides Sub ProcessRequest(ByVal context As HttpContext)
            AdminRequired = False
            MyBase.AdminRequired = False
            MyBase.ProcessRequest(context)
            Dim sOut As String = "{""result"":""success""}"
            Dim action As Actions = Actions.None
            If Not Params Is Nothing AndAlso Params.Count > 0 Then
                If Not Params("action") Is Nothing AndAlso IsNumeric(Params("action")) Then
                    action = CType(CInt(Params("action").ToString), Actions)
                End If
            ElseIf Not HttpContext.Current.Request.QueryString("action") Is Nothing AndAlso IsNumeric(HttpContext.Current.Request.QueryString("action")) Then
                If Integer.Parse(HttpContext.Current.Request.QueryString("action")) = 11 Then
                    action = Actions.TagsAutoComplete
                End If
            End If
            Select Case action
                Case Actions.UserPing
                    sOut = UserOnline()
                Case Actions.GetUsersOnline
                    sOut = GetUserOnlineList()
                Case Actions.TopicSubscribe
                    sOut = SubscribeTopic()
                Case Actions.ForumSubscribe
                    sOut = SubscribeForum()
                Case Actions.RateTopic
                    sOut = RateTopic()
                Case Actions.DeleteTopic
                    sOut = DeleteTopic()
                Case Actions.MoveTopic
                    sOut = MoveTopic()
                Case Actions.PinTopic
                    sOut = PinTopic()
                Case Actions.LockTopic
                    sOut = LockTopic()
                Case Actions.MarkAnswer
                    sOut = MarkAnswer()
                Case Actions.TagsAutoComplete
                    sOut = TagsAutoComplete()
                Case Actions.DeletePost
                    sOut = DeletePost()
                Case Actions.LoadTopic
                    sOut = LoadTopic()
                Case Actions.SaveTopic
                    sOut = SaveTopic()
                Case Actions.ForumList
                    sOut = ForumList()
            End Select
            context.Response.ContentType = "text/plain"
            context.Response.Write(sOut)
        End Sub
        Private Function ForumList() As String
            Dim fc As New ForumController()
            Return fc.GetForumsHtmlOption(PortalId, ModuleId, ForumUser)
        End Function
        Private Function UserOnline() As String
            Try
                If UserId > 0 Then
                    DataProvider.Instance.Profiles_UpdateActivity(PortalId, ModuleId, UserId)
                    Return BuildOutput(UserId.ToString, OutputCodes.Success, True, False)
                Else
                    Return BuildOutput(UserId.ToString, OutputCodes.AccessDenied, True, False)
                End If

            Catch ex As Exception
                Return BuildOutput(ex.Message, OutputCodes.AccessDenied, False, False)
            End Try
        End Function
        Private Function GetUserOnlineList() As String
            Dim uo As New UsersOnline
            Dim sOnlineList As String = uo.GetUsersOnline(PortalId, ModuleId, UserId)
            Dim dr As IDataReader = DataProvider.Instance.Profiles_GetStats(PortalId, ModuleId, 2)
            Dim anonCount As Integer = 0
            Dim memCount As Integer = 0
            Dim memTotal As Integer = 0
            While dr.Read
                anonCount = CInt(dr("Guests"))
                memCount = CInt(dr("Members"))
                memTotal = CInt(dr("MembersTotal"))
            End While
            dr.Close()
            Dim sUsersOnline As String
            sUsersOnline = Utilities.GetSharedResource("[RESX:UsersOnline]")
            sUsersOnline = Replace(sUsersOnline, "[USERCOUNT]", memCount.ToString)
            sUsersOnline = Replace(sUsersOnline, "[TOTALMEMBERCOUNT]", memTotal.ToString)
            Return BuildOutput(sUsersOnline & " " & sOnlineList, OutputCodes.Success, True, False)
        End Function
        Private Function SubscribeTopic() As String
            If UserId <= 0 Then
                Return BuildOutput(String.Empty, OutputCodes.AuthenticationFailed, True)
            End If
            Dim iStatus As Integer = 0
            Dim sc As New SubscriptionController
            Dim forumId As Integer = -1
            Dim topicId As Integer = -1
            If Params.ContainsKey("forumid") AndAlso IsNumeric(Params("forumid")) Then
                forumId = Integer.Parse(Params("forumid").ToString)
            End If
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            iStatus = sc.Subscription_Update(PortalId, ModuleId, forumId, topicId, 1, Me.UserId, ForumUser.UserRoles)
            If iStatus = 1 Then
                Return BuildOutput("{""subscribed"":true,""text"":""" & Utilities.JSON.EscapeJsonString(Utilities.GetSharedResource("[RESX:TopicSubscribe:TRUE]")) & """}", OutputCodes.Success, True, True)
            Else
                Return BuildOutput("{""subscribed"":false,""text"":""" & Utilities.JSON.EscapeJsonString(Utilities.GetSharedResource("[RESX:TopicSubscribe:FALSE]")) & """}", OutputCodes.Success, True, True)
            End If
        End Function
        Private Function SubscribeForum() As String
            If UserId <= 0 Then
                Return BuildOutput(String.Empty, OutputCodes.AuthenticationFailed, True)
            End If
            Dim rUserId As Integer = -1

            If Params.ContainsKey("userid") AndAlso IsNumeric(Params("userid")) Then
                rUserId = Integer.Parse(Params("userid").ToString)

            End If
            If rUserId > 0 And rUserId <> ForumUser.UserId And Not ForumUser.IsAdmin Then
                Return BuildOutput(String.Empty, OutputCodes.AuthenticationFailed, True)
            End If
            rUserId = UserId
            Dim iStatus As Integer = 0
            Dim sc As New SubscriptionController
            Dim forumId As Integer = -1
            If Params.ContainsKey("forumid") AndAlso IsNumeric(Params("forumid")) Then
                forumId = Integer.Parse(Params("forumid").ToString)
            End If
            iStatus = sc.Subscription_Update(PortalId, ModuleId, forumId, -1, 1, rUserId, ForumUser.UserRoles)

            If iStatus = 1 Then
                Return BuildOutput("{""subscribed"":true,""text"":""" & Utilities.JSON.EscapeJsonString(Utilities.GetSharedResource("[RESX:ForumSubscribe:TRUE]")) & """,""forumid"":" & forumId.ToString & "}", OutputCodes.Success, True, True)
            Else
                Return BuildOutput("{""subscribed"":false,""text"":""" & Utilities.JSON.EscapeJsonString(Utilities.GetSharedResource("[RESX:ForumSubscribe:FALSE]")) & """,""forumid"":" & forumId.ToString & "}", OutputCodes.Success, True, True)
            End If


        End Function
        Private Function RateTopic() As String
            Dim r As Integer = 0
            Dim topicId As Integer = -1
            If Params.ContainsKey("rate") AndAlso IsNumeric(Params("rate")) Then
                r = Integer.Parse(Params("rate").ToString)
            End If
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If r >= 1 And r <= 5 And topicId > 0 Then
                DataProvider.Instance.Topics_AddRating(topicId, UserId, r, String.Empty, HttpContext.Current.Request.UserHostAddress.ToString)
            End If
            r = DataProvider.Instance.Topics_GetRating(topicId)
            Return BuildOutput(r.ToString, OutputCodes.Success, True, False)
        End Function
        Private Function DeleteTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
                If Not f Is Nothing Then
                    If Permissions.HasPerm(f.Security.ModDelete, ForumUser.UserRoles) Or (t.Author.AuthorId = Me.UserId And Permissions.HasAccess(f.Security.Delete, ForumUser.UserRoles)) Then
                        tc.Topics_Delete(PortalId, ModuleId, forumId, topicId, MainSettings.DeleteBehavior)
                        Return BuildOutput(String.Empty, OutputCodes.Success, True)
                    End If
                End If
            End If
            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function MoveTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            Dim targetForumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If Params.ContainsKey("forumid") AndAlso IsNumeric(Params("forumid")) Then
                targetForumId = Integer.Parse(Params("forumid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
                If Not f Is Nothing Then
                    If Permissions.HasPerm(f.Security.ModMove, ForumUser.UserRoles) Then
                        tc.Topics_Move(PortalId, ModuleId, targetForumId, topicId)
                        DataCache.ClearAllCache(ModuleId, TabId)
                        Return BuildOutput(String.Empty, OutputCodes.Success, True)
                    End If
                End If

            End If
            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function PinTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
                If Not f Is Nothing Then
                    If Permissions.HasPerm(f.Security.ModPin, ForumUser.UserRoles) Or (t.Author.AuthorId = Me.UserId And Permissions.HasAccess(f.Security.Pin, ForumUser.UserRoles)) Then
                        If t.IsPinned Then
                            t.IsPinned = False
                        Else
                            t.IsPinned = True
                        End If
                        tc.TopicSave(PortalId, t)
                        Return BuildOutput(String.Empty, OutputCodes.Success, True)
                    End If
                End If
            End If
            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function LockTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
                If Not f Is Nothing Then
                    If Permissions.HasPerm(f.Security.ModLock, ForumUser.UserRoles) Or (t.Author.AuthorId = Me.UserId And Permissions.HasAccess(f.Security.Lock, ForumUser.UserRoles)) Then
                        If t.IsLocked Then
                            t.IsLocked = False
                        Else
                            t.IsLocked = True
                        End If
                        tc.TopicSave(PortalId, t)
                        Return BuildOutput(String.Empty, OutputCodes.Success, True)
                    End If
                End If
            End If
            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function MarkAnswer() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            Dim replyId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If Params.ContainsKey("replyid") AndAlso IsNumeric(Params("replyid")) Then
                replyId = Integer.Parse(Params("replyid").ToString)
            End If
            If topicId > 0 And UserId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
                If (Me.UserId = t.Author.AuthorId And Not t.IsLocked) Or Permissions.HasAccess(f.Security.ModEdit, ForumUser.UserRoles) Then
                    DataProvider.Instance.Reply_UpdateStatus(PortalId, ModuleId, topicId, replyId, UserId, 1, Permissions.HasAccess(f.Security.ModEdit, ForumUser.UserRoles))

                End If
                Return BuildOutput(String.Empty, OutputCodes.Success, True)
            Else
                Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
            End If
        End Function
        Private Function TagsAutoComplete() As String
            Dim sb As New Text.StringBuilder
            Dim q As String = String.Empty
            If Not String.IsNullOrEmpty(HttpContext.Current.Request.QueryString("q")) Then
                q = HttpContext.Current.Request.QueryString("q").Trim
                q = Utilities.Text.RemoveHTML(q)
                q = Utilities.Text.CheckSqlString(q)
                If Not String.IsNullOrEmpty(q) Then
                    If q.Length > 20 Then
                        q = q.Substring(0, 20)
                    End If
                End If
            End If
            Dim i As Integer = 0
            If Not String.IsNullOrEmpty(q) Then
                Using dr As IDataReader = DataProvider.Instance.Tags_Search(PortalId, ModuleId, q)
                    While dr.Read()
                        sb.AppendLine("{""id"":""" & dr("TagId").ToString & """,""name"":""" & dr("TagName").ToString & """,""type"":""0""},")
                        i += 1
                    End While
                    dr.Close()
                End Using
            End If
            Dim out As String = "["
            If i > 0 Then
                out &= sb.ToString.Trim
                out = out.Substring(0, out.Length - 1)
            End If
            out &= "]"
            Return out
        End Function
        Private Function DeletePost() As String
            Dim replyId As Integer = -1
            Dim TopicId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                TopicId = Integer.Parse(Params("topicid").ToString)
            End If
            If Params.ContainsKey("replyid") AndAlso IsNumeric(Params("replyid")) Then
                replyId = Integer.Parse(Params("replyid").ToString)
            End If
            Dim forumId As Integer = -1
            Dim db As New Data.ForumsDB
            forumId = db.Forum_GetByTopicId(TopicId)
            Dim fc As New ForumController
            Dim f As Forum = fc.Forums_Get(forumId, Me.UserId, True)
            If TopicId > 0 And replyId < 1 Then
                Dim tc As New TopicsController
                Dim ti As TopicInfo = tc.Topics_Get(PortalId, ModuleId, TopicId)

                If Permissions.HasAccess(f.Security.ModDelete, ForumUser.UserRoles) Or (Permissions.HasAccess(f.Security.Delete, ForumUser.UserRoles) And ti.Content.AuthorId = UserId And ti.IsLocked = False) Then
                    DataProvider.Instance.Topics_Delete(forumId, TopicId, MainSettings.DeleteBehavior)
                Else
                    Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
                End If
            Else
                Dim rc As New ReplyController
                Dim ri As ReplyInfo = rc.Reply_Get(PortalId, ModuleId, TopicId, replyId)
                If Permissions.HasAccess(f.Security.ModDelete, ForumUser.UserRoles) Or (Permissions.HasAccess(f.Security.Delete, ForumUser.UserRoles) And ri.Content.AuthorId = UserId) Then
                    DataProvider.Instance.Reply_Delete(forumId, TopicId, replyId, MainSettings.DeleteBehavior)
                Else
                    Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
                End If

            End If
            Return BuildOutput(TopicId & "|" & replyId, OutputCodes.Success, True)
        End Function
        Private Function LoadTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(PortalId, -1, forumId, Me.UserId, True, False, -1)
                If Not f Is Nothing Then
                    If Permissions.HasPerm(f.Security.ModEdit, ForumUser.UserRoles) Then
                        Dim sb As New StringBuilder()
                        sb.Append("{")
                        sb.Append(Utilities.JSON.Pair("topicid", t.TopicId.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("subject", t.Content.Subject))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("authorid", t.Content.AuthorId.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("locked", t.IsLocked.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("pinned", t.IsPinned.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("priority", t.Priority.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("status", t.StatusId.ToString))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("forumid", forumId.ToString()))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("forumname", f.ForumName))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("tags", t.Tags))
                        sb.Append(",")
                        sb.Append(Utilities.JSON.Pair("categories", t.Categories))
                        sb.Append(",")
                        sb.Append("""properties"":[")
                        Dim sCats As String = String.Empty
                        If Not f.Properties Is Nothing Then
                            Dim i As Integer = 0
                            For Each p As PropertiesInfo In f.Properties
                                sb.Append("{")
                                sb.Append(Utilities.JSON.Pair("propertyid", p.PropertyId.ToString))
                                sb.Append(",")
                                sb.Append(Utilities.JSON.Pair("datatype", p.DataType))
                                sb.Append(",")
                                sb.Append(Utilities.JSON.Pair("propertyname", p.Name))
                                sb.Append(",")
                                Dim pvalue As String = p.DefaultValue
                                For Each tp As PropertiesInfo In t.TopicProperties
                                    If tp.PropertyId = p.PropertyId Then
                                        pvalue = tp.DefaultValue
                                    End If
                                Next

                                sb.Append(Utilities.JSON.Pair("propertyvalue", pvalue))
                                If p.DataType.Contains("list") Then
                                    sb.Append(",""listdata"":[")
                                    If p.DataType.Contains("list|categories") Then
                                        Using dr As IDataReader = DataProvider.Instance.Tags_List(PortalId, f.ModuleId, True, 0, 200, "ASC", "TagName", forumId, f.ForumGroupId)
                                            dr.NextResult()
                                            While dr.Read
                                                sCats &= "{"
                                                sCats &= Utilities.JSON.Pair("id", dr("TagId").ToString)
                                                sCats &= ","
                                                sCats &= Utilities.JSON.Pair("name", dr("TagName").ToString)
                                                sCats &= ","
                                                sCats &= Utilities.JSON.Pair("selected", IsSelected(dr("TagName").ToString, t.Categories).ToString)
                                                sCats &= "},"
                                            End While
                                            dr.Close()
                                        End Using
                                        If Not String.IsNullOrEmpty(sCats) Then
                                            sCats = sCats.Substring(0, sCats.Length - 1)
                                        End If
                                        sb.Append(sCats)
                                    Else
                                        Dim lists As New DotNetNuke.Common.Lists.ListController
                                        Dim lName As String = p.DataType.Substring(p.DataType.IndexOf("|") + 1)
                                        Dim lc As DotNetNuke.Common.Lists.ListEntryInfoCollection = lists.GetListEntryInfoCollection(lName, String.Empty)
                                        Dim il As Integer = 0
                                        For Each l As DotNetNuke.Common.Lists.ListEntryInfo In lc
                                            sb.Append("{")
                                            sb.Append(Utilities.JSON.Pair("itemId", l.Value))
                                            sb.Append(",")
                                            sb.Append(Utilities.JSON.Pair("itemName", l.Text))
                                            sb.Append("}")
                                            il += 1
                                            If il < lc.Count Then
                                                sb.Append(",")
                                            End If
                                        Next
                                    End If
                                    sb.Append("]")
                                End If
                                sb.Append("}")
                                i += 1
                                If i < f.Properties.Count Then
                                    sb.Append(",")
                                End If

                            Next
                        End If
                        



                        sb.Append("],""categories"":[")
                        sCats = String.Empty
                        Using dr As IDataReader = DataProvider.Instance.Tags_List(PortalId, f.ModuleId, True, 0, 200, "ASC", "TagName", forumId, f.ForumGroupId)
                            dr.NextResult()
                            While dr.Read
                                sCats &= "{"
                                sCats &= Utilities.JSON.Pair("id", dr("TagId").ToString)
                                sCats &= ","
                                sCats &= Utilities.JSON.Pair("name", dr("TagName").ToString)
                                sCats &= ","
                                sCats &= Utilities.JSON.Pair("selected", IsSelected(dr("TagName").ToString, t.Categories).ToString)
                                sCats &= "},"
                            End While
                            dr.Close()
                        End Using
                        If Not String.IsNullOrEmpty(sCats) Then
                            sCats = sCats.Substring(0, sCats.Length - 1)
                        End If
                        sb.Append(sCats)
                        sb.Append("]")
                        sb.Append("}")
                        Return BuildOutput(sb.ToString, OutputCodes.Success, True, True)
                    End If
                End If

            End If
            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function SaveTopic() As String
            Dim topicId As Integer = -1
            Dim forumId As Integer = -1
            If Params.ContainsKey("topicid") AndAlso IsNumeric(Params("topicid")) Then
                topicId = Integer.Parse(Params("topicid").ToString)
            End If
            If topicId > 0 Then
                Dim tc As New TopicsController
                Dim t As TopicInfo = tc.Topics_Get(PortalId, ModuleId, topicId)
                Dim db As New Data.ForumsDB
                forumId = db.Forum_GetByTopicId(topicId)
                Dim fc As New ForumController
                Dim f As Forum = fc.Forums_Get(PortalId, -1, forumId, Me.UserId, True, False, -1)
                If Permissions.HasPerm(f.Security.ModEdit, ForumUser.UserRoles) Then
                    Dim subject As String = Params("subject").ToString
                    subject = Utilities.XSSFilter(subject, True)
                    If Not String.IsNullOrEmpty(f.PrefixURL) Then
                        Dim cleanSubject As String = Utilities.CleanName(Subject).ToLowerInvariant
                        If IsNumeric(cleanSubject) Then
                            cleanSubject = "Topic-" & cleanSubject
                        End If
                        Dim topicUrl As String = cleanSubject
                        Dim urlPrefix As String = "/"
                        If Not String.IsNullOrEmpty(f.ForumGroup.PrefixURL) Then
                            urlPrefix &= f.ForumGroup.PrefixURL & "/"
                        End If
                        If Not String.IsNullOrEmpty(f.PrefixURL) Then
                            urlPrefix &= f.PrefixURL & "/"
                        End If
                        Dim urlToCheck As String = urlPrefix & cleanSubject
                        Dim topicsDb As New Data.Topics
                        For u As Integer = 0 To 200
                            Dim tid As Integer = topicsDb.TopicIdByUrl(PortalId, f.ModuleId, urlToCheck)
                            If tid > 0 And tid = topicId Then
                                Exit For
                            ElseIf tid > 0 Then
                                topicUrl = (u + 1) & "-" & cleanSubject
                                urlToCheck = urlPrefix & topicUrl
                            Else
                                Exit For
                            End If
                        Next
                        If topicUrl.Length > 150 Then
                            topicUrl = topicUrl.Substring(0, 149)
                            topicUrl = topicUrl.Substring(0, topicUrl.LastIndexOf("-"))
                        End If
                        t.TopicUrl = topicUrl
                        '.URL = topicUrl
                    Else
                        '.URL = String.Empty
                        t.TopicUrl = String.Empty
                    End If
                    t.Content.Subject = subject
                    t.IsPinned = Boolean.Parse(Params("pinned").ToString)
                    t.IsLocked = Boolean.Parse(Params("locked").ToString)
                    t.Priority = Integer.Parse(Params("priority").ToString)
                    t.StatusId = Integer.Parse(Params("status").ToString)
                    If Not f.Properties Is Nothing Then
                        Dim tData As New StringBuilder
                        tData.Append("<topicdata>")
                        tData.Append("<properties>")
                        For Each p As PropertiesInfo In f.Properties
                            Dim pkey As String = "prop-" & p.PropertyId.ToString

                            tData.Append("<property id=""" & p.PropertyId.ToString & """>")
                            tData.Append("<name><![CDATA[")
                            tData.Append(p.Name)
                            tData.Append("]]></name>")
                            If Not Params(pkey) Is Nothing Then
                                tData.Append("<value><![CDATA[")
                                tData.Append(Utilities.XSSFilter(Params(pkey).ToString))
                                tData.Append("]]></value>")
                            Else
                                tData.Append("<value></value>")
                            End If
                            tData.Append("</property>")
                        Next
                        tData.Append("</properties>")
                        tData.Append("</topicdata>")
                        t.TopicData = tData.ToString
                    End If
                End If
                tc.TopicSave(PortalId, t)
                If Not Params("tags") Is Nothing Then
                    DataProvider.Instance.Tags_DeleteByTopicId(PortalId, f.ModuleId, topicId)
                    Dim tagForm As String = String.Empty
                    If Not Params("tags") Is Nothing Then
                        tagForm = Params("tags").ToString
                    End If
                    If Not tagForm = String.Empty Then
                        Dim Tags() As String = tagForm.Split(CChar(","))
                        Dim tag As String = String.Empty
                        For Each tag In Tags
                            Dim sTag As String = Utilities.CleanString(PortalId, tag.Trim, False, EditorTypes.TEXTBOX, False, False, f.ModuleId, String.Empty, False)
                            DataProvider.Instance.Tags_Save(PortalId, f.ModuleId, -1, sTag, 0, 1, 0, topicId, False, -1, -1)
                        Next
                    End If
                End If
                
                If Not Params("categories") Is Nothing Then
                    Dim cats() As String = Params("categories").ToString.Split(CChar(";"))
                    DataProvider.Instance.Tags_DeleteTopicToCategory(PortalId, f.ModuleId, -1, topicId)
                    For Each c As String In cats
                        Dim cid As Integer = -1
                        If Not String.IsNullOrEmpty(c) AndAlso IsNumeric(c) Then
                            cid = CInt(c)
                            If cid > 0 Then
                                DataProvider.Instance.Tags_AddTopicToCategory(PortalId, f.ModuleId, cid, topicId)
                            End If
                        End If
                    Next
                End If
            End If
            

            Return BuildOutput(String.Empty, OutputCodes.UnsupportedRequest, False)
        End Function
        Private Function IsSelected(ByVal TagName As String, ByVal selectedValues As String) As Boolean
            If String.IsNullOrEmpty(SelectedValues) Then
                Return False
            Else
                For Each s As String In SelectedValues.Split(CChar("|"))
                    If Not String.IsNullOrEmpty(s) Then
                        If s.ToLowerInvariant.Trim = TagName.ToLowerInvariant.Trim Then
                            Return True
                        End If
                    End If
                Next
            End If

        End Function
    End Class
End Namespace